using System;
using System.Collections.Generic;
using System.Text;
using Dsp;

namespace esl.chk
{
    /// <summary>
    /// Illustrates the use of the dcomplex class.
    /// </summary>
    public class Test_dcomplex
    {
        static public void Test()
        {
            //
            // dcomplex constants:
            //
            Console.WriteLine("dcomplex.Zero = {0}", Complex.Zero);
            Console.WriteLine("dcomplex.One = {0}", Complex.One);
            // The imaginary unit is given by dcomplex.I:
            Console.WriteLine("dcomplex.I = {0}", Complex.I);
            Console.WriteLine();

            // Construct some complex numbers
            //
            // Real and imaginary parts:
            //   a = 2 + 4i
            Complex a = new Complex(2, 4);
            Console.WriteLine("a = {0}", a);
            //   b = 1 - 3i
            Complex b = new Complex(1, -3);
            Console.WriteLine("b = {0}", b.ToString());
            // From a real number:
            //   c = -3 + 0i
            Complex c = new Complex(-3);
            Console.WriteLine("c = {0}", c.ToString());
            // Polar form:
            //   d = 2 (cos(Pi/3) + i sin(Pi/3))
            Complex d = Complex.Polar(2, Constants.Pi/3);
            // To print this number, use the overloaded ToString
            // method and specify the format string for the real 
            // and imaginary parts:
            Console.WriteLine("d = {0}", d.ToString("F4"));
            Console.WriteLine();

            //
            // Parts of complex numbers
            //
            Console.WriteLine("Parts of a = {0}:", a);
            Console.WriteLine("Real part of a = {0}", a.Re);
            Console.WriteLine("Imaginary part of a = {0}", a.Im);
            Console.WriteLine("Modulus of a = {0}", a.Abs);
            Console.WriteLine("Argument of a = {0}", a.Arg);
            Console.WriteLine();

            //
            // Basic arithmetic:
            //
            Console.WriteLine("Basic arithmetic:");
            Complex e = -a;
            Console.WriteLine("-a = {0}", e);
            e = a + b;
            Console.WriteLine("a + b = {0}", e);
            e = a - b;
            Console.WriteLine("a - b = {0}", e);
            e = a * b;
            Console.WriteLine("a * b = {0}", e);
            e = a / b;
            Console.WriteLine("a / b = {0}", e);
            // The conjugate of a complex number corresponds to
            // the ~ operator:
            e = ~a;
            Console.WriteLine("Conjugate(a) = ~a = {0}", e);
            Console.WriteLine();

            //
            // Functions of complex numbers
            //
            // Most of these have corresponding static methods 
            // in the System.Math class, but are extended to complex 
            // arguments.
            Console.WriteLine("Functions of complex numbers:");
            /*
            // Exponentials and logarithms
            Console.WriteLine("Exponentials and logarithms:");
            e = dcomplex.Exp(a);
            Console.WriteLine("Exp(a) = {0}", e.ToString("F4"));
            e = dcomplex.Log(a);
            Console.WriteLine("Log(a) = {0}", e.ToString("F4"));
            e = dcomplex.Log10(a);
            Console.WriteLine("Log10(a) = {0}", e.ToString("F4"));
            // You can get a point on the unit circle by calling
            // the ExpI method:
            e = dcomplex.ExpI(2*Constants.Pi/3);
            Console.WriteLine("ExpI(2*Pi/3) = {0}", e.ToString("F4"));
            // The RootOfUnity method also returns points on the
            // unit circle. The above is equivalent to the second
            // root of z^6 = 1:
            e = dcomplex.RootOfUnity(6, 2);
            Console.WriteLine("RootOfUnity(6, 2) = {0}", e.ToString("F4"));


            // The Pow method is overloaded for integer, double,
            // and complex argument:
            e = dcomplex.Pow(a, 3);
            Console.WriteLine("Pow(a,3) = {0}", e.ToString("F4"));
            e = dcomplex.Pow(a, 1.5);
            Console.WriteLine("Pow(a,1.5) = {0}", e.ToString("F4"));
            e = dcomplex.Pow(a, b);
            Console.WriteLine("Pow(a,b) = {0}", e.ToString("F4"));

            // Square root
            e = dcomplex.Sqrt(a);
            Console.WriteLine("Sqrt(a) = {0}", e.ToString("F4"));
            // The Sqrt method is overloaded. Here's the square 
            // root of a negative double:
            e = dcomplex.Sqrt(-4);
            Console.WriteLine("Sqrt(-4) = {0}", e.ToString("F4"));
            Console.WriteLine();

            //
            // Trigonometric functions:
            //
            Console.WriteLine("Trigonometric function:");
            e = dcomplex.Sin(a);
            Console.WriteLine("Sin(a) = {0}", e.ToString("F4"));
            e = dcomplex.Cos(a);
            Console.WriteLine("Cos(a) = {0}", e.ToString("F4"));
            e = dcomplex.Tan(a);
            Console.WriteLine("Tan(a) = {0}", e.ToString("F4"));

            // Inverse Trigonometric functions:
            e = dcomplex.Asin(a);
            Console.WriteLine("Asin(a) = {0}", e.ToString("F4"));
            e = dcomplex.Acos(a);
            Console.WriteLine("Acos(a) = {0}", e.ToString("F4"));
            e = dcomplex.Atan(a);
            Console.WriteLine("Atan(a) = {0}", e.ToString("F4"));

            // Asin and Acos have overloads with real argument
            // not restricted to [-1,1]:
            e = dcomplex.Asin(2);
            Console.WriteLine("Asin(2) = {0}", e.ToString("F4"));
            e = dcomplex.Acos(2);
            Console.WriteLine("Acos(2) = {0}", e.ToString("F4"));
            Console.WriteLine();
            
            //
            // Hyperbolic and inverse hyperbolic functions:
            //
            Console.WriteLine("Hyperbolic function:");
            e = dcomplex.Sinh(a);
            Console.WriteLine("Sinh(a) = {0}", e.ToString("F4"));
            e = dcomplex.Cosh(a);
            Console.WriteLine("Cosh(a) = {0}", e.ToString("F4"));
            e = dcomplex.Tanh(a);
            Console.WriteLine("Tanh(a) = {0}", e.ToString("F4"));
            e = dcomplex.Asinh(a);
            Console.WriteLine("Asinh(a) = {0}", e.ToString("F4"));
            e = dcomplex.Acosh(a);
            Console.WriteLine("Acosh(a) = {0}", e.ToString("F4"));
            e = dcomplex.Atanh(a);
            Console.WriteLine("Atanh(a) = {0}", e.ToString("F4"));
            Console.WriteLine();
            */
            Console.Write("Press Enter key to exit...");
            Console.ReadLine();
        }
    }
}